package com.twoscreen;

import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;

@PersistenceCapable
public class Points {
	@NotPersistent
	private static PersistenceManager pm = PMF.get().getPersistenceManager();
	
	@NotPersistent
	private static final Logger log = Logger.getLogger("com.twoscreen.Points.java");
	
	@NotPersistent
	private static final String viewerIdPropertyName = "viewerId";
	
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Key key;
	
	@Persistent
	private String viewerId; //foreign key to TUser
	
	@Persistent
	private long questionId;
	
	@Persistent
	private int points;
	
	@Persistent
	private Date timeStamp;
	
	public Points(String viewerId, long questionId, int points) {
		this.viewerId = viewerId;
		this.questionId = questionId;
		this.points = points;
		this.timeStamp = new Date();
		pm.makePersistent(this);
		log.info("Points added: viewerId: " + viewerId +
				" questionId: " + questionId +
				" number of points: " + points);
	}
	
	public String getViewerId() {
		return viewerId;
	}

	public long getQuestionId() {
		return questionId;
	}

	public int getPoints() {
		return points;
	}

	/**
	 * Returns a pre-formatted total points for a given TUser object.
	 * The formatting is to round the number into thousands, millions, and trillions
	 * ensuring the returned string is understandable to the user
	 * @param tuser The TUser object to search by
	 * @return A String containing a formatted number of points
	 */
	public static String getPointsTotal(TUser tuser) {
		int totalPoints = 0;
		String points = null;
		log.info("Getting points for viewer ID: " + tuser.getViewerId());
		String viewerId = tuser.getViewerId();
		Query q = pm.newQuery(Points.class);
		q.setFilter(viewerIdPropertyName + " == viewerIdParam");
		q.declareParameters("String viewerIdParam");

		//Sum the points for the viewerId
		try {
			@SuppressWarnings("unchecked")
			List<Points> results = (List<Points>) q.execute(viewerId);
			for (Points result : results) {
				totalPoints += result.getPoints();
			}
		} finally {
			q.closeAll();
		}
		
		//Convert points to a short string
		if (totalPoints > 1000000000) {
			int p = totalPoints/1000000000;
			points = p + "t";
		} else if (totalPoints > 1000000) {
			int p = totalPoints/1000000;
			points = p + "m";
		} else if (totalPoints > 1000) {
			int p = totalPoints/1000;
			points = p + "k";
		} else {
			points = String.valueOf(totalPoints);
		}
		
		return points;
	}
	
	/**
	 * Returns an array of Points objects based on the viewer ID passed
	 * @param viewerId Viewer ID to search by
	 * @return List of Points objects
	 */
	public static List<Points> getPointsList(String viewerId) {
		log.info("Getting points list for viewer ID: " + viewerId);
		Query q = pm.newQuery(Points.class);
		q.setFilter(viewerIdPropertyName + " == viewerIdParam");
		q.declareParameters("String questionIdParam");

		//Sum the points for the viewerId
		@SuppressWarnings("unchecked")
		List<Points> results = (List<Points>) q.execute(viewerId);
		
		q.closeAll();
		
		return results;
	}

}
